//十六进制字符串转字节数组
function hex2Bytes(str) {
	var pos = 0;
	var len = str.length;
	if (len % 2 != 0) {
		return null;
	}
	len /= 2;
	var hexA = new Array();

	for (var i = 0; i < len; i++) {
		var s = str.substr(pos, 2);
		var v = parseInt(s, 16);
		hexA.push(v);
		pos += 2;
	}
	return hexA;
}
// ArrayBuffer转16进度字符串
function ab2hex(buffer) {
	var hexArr = Array.prototype.map.call(
		new Uint8Array(buffer),
		function(bit) {
			return ('00' + bit.toString(16)).slice(-2)
		}
	)
	return hexArr.join('');
}

function Action() {
	Action_GETHCESTATUS = 0
	Action_STARTHCE = 1
	Action_SENDMESSAGE = 2
	Action_RECEIVEMESSAGE = 3
	Action_STOPHCE = 4
}
var tools = {
	hexToString: function(hexCharCodeStr) {
		var trimedStr = hexCharCodeStr.trim();
		var rawStr =
			trimedStr.substr(0, 2).toLowerCase() === "0x" ?
			trimedStr.substr(2) :
			trimedStr;
		var len = rawStr.length;
		if (len % 2 !== 0) {
			alert("Illegal Format ASCII Code!");
			return "";
		}
		var curCharCode;
		var resultStr = [];
		for (var i = 0; i < len; i = i + 2) {
			curCharCode = parseInt(rawStr.substr(i, 2), 16); // ASCII Code Value
			resultStr.push(String.fromCharCode(curCharCode));
		}
		return resultStr.join("");
	},
	stringToHex: function(str) {
		var val = "";
		for (var i = 0; i < str.length; i++) {
			if (val == "")
				val = str.charCodeAt(i).toString(16);
			else
				val += str.charCodeAt(i).toString(16);
		}
		return val;
	},
	//补零
	plusZero: function(_str) {
		while (_str.length % 2 != 0) {
			_str += "0"
		}
		return _str
	},
	pad: function(num, n) {
		var len = num.toString().length;
		while (len < n) {
			num = "0" + num;
			len++;
		}
		return num;
	}
}
var Status = [{
		code: '0',
		msg: 'OK'
	},
	{
		code: '13000',
		msg: '当前设备不支持 NFC'
	},
	{
		code: '13001',
		msg: '当前设备支持 NFC，但系统NFC开关未开启'
	},
	{
		code: '13002',
		msg: '当前设备支持 NFC，但不支持HCE'
	},
	{
		code: '13003',
		msg: 'AID 列表参数格式错误'
	},
	{
		code: '13004',
		msg: '未设置微信为默认NFC支付应用'
	},
	{
		code: '13005',
		msg: '返回的指令不合法'
	},
	{
		code: '13006',
		msg: '注册 AID 失败'
	}
]
class NfcHCE {
	/**
	 * @param {Object} mContext
	 * @param {Object} _aids
	 * @param {Object} mMsgCallBack mMsgCallBack(res.errCode,res.errMsg)
	 * @param {Object} onNfcMessageLinsener onNfcMessageLinsener(res.messageType, res.reason, ab2hex(res.data)) 收到读卡器发来的消息
	 */
	constructor(_aids, mMsgCallBack, onNfcMessageLinsener) {
		this.aids = _aids
		this.mCallBack = mMsgCallBack
		this.nfcMessageCallBack = onNfcMessageLinsener
	}
	/**
	 * 1获取当前状态,判断当前设备是否支持 HCE 能力。
	 */
	getNfcStatus() {
		var that = this
		wx.getHCEState({
			success: function(res) {
				console.log('NfcHCECore-->getNfcStatus::success:', res)
				that._runCallBack(res.errCode, res.errMsg)
				//console.error("状态："+res.errCode+"="+res.errMsg)
			},
			fail: function(err) {
				console.error('NfcHCECore-->getNfcStatus::fail:', err)
				that.callError(err) 
				//console.error("状态2："+err)
			}
		})
	}
	/**
	 * 2开启HCE环境，初始化 NFC 模块。
	 */
	startNfcHCE() {
		var that = this
		wx.startHCE({
			aid_list: this.aids,
			success: function(res) {
				console.log('NfcHCECore-->startNfcHCE::success:', res)
				that._runCallBack(res.errCode, res.errMsg)
			},
			fail: function(err) {
				console.error('NfcHCECore-->startNfcHCE::fail:', err)
				that.callError(err)
			}
		})
	}
	/**
	 * 发生消息，发送 NFC 消息。仅在安卓系统下有效
	 */
	sendNfcHCEMessage(hexApdu) {
		console.log('开始发送发回')
		var that = this
		var byteArrays = hex2Bytes(hexApdu)
		var retbuffer = new ArrayBuffer(byteArrays.length)
		var dataView = new DataView(retbuffer)
		for (var i = 0; i < dataView.byteLength; i++) {
			dataView.setInt8(i, byteArrays[i])
		}
		wx.sendHCEMessage({
			data: retbuffer,
			success: function(res) {
				console.log('NfcHCECore-->sendNfcHCEMessage::success:', res)
				that._runCallBack(res.errCode, res.errMsg)
			},
			fail: function(err) {
				console.error('NfcHCECore-->sendNfcHCEMessage::fail:', err)
				that.callError(err)
			}
		})
	}
	/**
	 * 收到读卡器发来的消息，监听接收 NFC 设备消息事件，仅能注册一个监听
	 */
	onNfcHCEMessageHadnler() {
		var that = this
		wx.onHCEMessage(function(res) {
			console.log('NfcHCECore-->onHCEMessage:', res)
			//messageType	number	消息类型  
			//1	HCE APDU Command类型，小程序需对此指令进行处理，并调用 sendHCEMessage 接口返回处理指令
			//2	设备离场事件类型
			//data	ArrayBuffer	messageType=1 时 ,客户端接收到 NFC 设备的指令 
			//reason	number	messageType=2 时，原因
			that.nfcMessageCallBack(res.messageType, res.reason, ab2hex(res.data))
		})
	}
	/**
	 * 接收 NFC 设备消息事件，取消事件监听。没搞明白有什么用
	 */
	offNfcHCEMessageHadnler() {
		var that = this
		wx.offHCEMessage(function(res) {
			console.log('NfcHCECore-->offHCEMessage:', res)
		})
	}
	/**
	 * 停止HCE环境，关闭 NFC 模块。仅在安卓系统下有效。
	 */
	stopNfcHCE() {
		var that = this
		wx.stopHCE({
			success: function(res) {
				console.log('NfcHCECore-->stopNfcHCE::success:', res)
				that._runCallBack(res.errCode, res.errMsg)
			},
			fail: function(err) {
				console.error('NfcHCECore-->stopNfcHCE::fail:', err)
				that.callError(err)
			}
		})
	}
	/**
	 * 简化nfc使用流程，判断hce状态=>开启hce=>监听接收nfc设备消息事件
	 */
	simple() {
		var that = this
		wx.getHCEState({
			success: function(res) {
				console.log('NfcHCECore-->simple::getHCEState:', res)
				console.log(that.aids)
				that._runCallBack(res.errCode, res.errMsg)
				//错误不继续执行
				if (res.errCode != "0") return;
				wx.startHCE({
					aid_list: that.aids,
					success: function(res) {
						console.log('NfcHCECore-->simple::startHCE:', res)
						that._runCallBack(res.errCode, res.errMsg)
						//错误不继续执行
						if (res.errCode != "0") return;
						wx.onHCEMessage(function(res) {
							console.log('NfcHCECore-->simple::onHCEMessage:', res)
							that.nfcMessageCallBack(res.messageType, res.reason, ab2hex(res.data))
						})
					},
					fail: function(err) {
						that.callError(err)
					}
				})
			},
			fail: function(err) {
				that.callError(err)
			}
		})
	}
	callError(err) {
		var that = this
		Status.forEach(function(value, index, list) {	
			//console.error("状态："+err.errCode+"=")
			if (value.code === ""+err.errCode) {
				//console.error("状态："+value.code+"="+value.msg)
				that._runCallBack(value.code, value.msg)
			}
		})
	}
	_runCallBack(status, data) {
		this.mCallBack(status, data)
	}
}
module.exports = {
	HCE: NfcHCE,
	tools: tools
}
